# coding=utf-8
import sys
from cal_interface import Ui_Calculator
from PyQt5.QtWidgets import *


class MyMainWindow(QMainWindow, Ui_Calculator):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)
        self.forge_link()  # 连接槽函数

    def forge_link(self):
        self.btn_num0.clicked.connect(lambda: self.button_event(0))
        self.btn_num1.clicked.connect(lambda: self.button_event(1))
        self.btn_num2.clicked.connect(lambda: self.button_event(2))
        self.btn_num3.clicked.connect(lambda: self.button_event(3))
        self.btn_num4.clicked.connect(lambda: self.button_event(4))
        self.btn_num5.clicked.connect(lambda: self.button_event(5))
        self.btn_num6.clicked.connect(lambda: self.button_event(6))
        self.btn_num7.clicked.connect(lambda: self.button_event(7))
        self.btn_num8.clicked.connect(lambda: self.button_event(8))
        self.btn_num9.clicked.connect(lambda: self.button_event(9))
        self.btn_add.clicked.connect(lambda: self.button_event('+'))
        self.btn_sub.clicked.connect(lambda: self.button_event('-'))
        self.btn_mul.clicked.connect(lambda: self.button_event('*'))
        self.btn_div.clicked.connect(lambda: self.button_event('/'))
        self.btn_dot.clicked.connect(lambda: self.button_event('.'))
        self.btn_l_bra.clicked.connect(lambda: self.button_event('('))
        self.btn_r_bra.clicked.connect(lambda: self.button_event(')'))
        self.btn_neg.clicked.connect(lambda: self.button_arithmetic("negate"))  # 取反
        self.btn_rec.clicked.connect(lambda: self.button_arithmetic("reciprocal"))  # 倒数
        self.btn_squ.clicked.connect(lambda: self.button_arithmetic("square"))  # 平方
        self.btn_rad.clicked.connect(lambda: self.button_arithmetic("radical"))  # 开方
        self.btn_cle.clicked.connect(self.clear_event)
        self.btn_del.clicked.connect(self.delete_event)
        self.btn_equ.clicked.connect(self.calc_complete)

    def button_event(self, arg):
        txt = self.line_edit.text()
        if arg in ('.', '+', '-', '*', '/'):  # 去掉小数点后多余的零
            for i in txt[::-1]:
                if i in ('+', '-', '*', '/'):
                    break
                elif i == '.':
                    if arg == '.':
                        arg = ''
                    for j in txt[::-1]:
                        if j == '0':
                            txt = txt[:-1]
                        else:
                            break
                else:
                    pass
        if (txt == '0' or txt == "-0") and arg not in ('.', '+', '*', '/'):
            self.line_edit.setText(str(arg))
        elif (txt[-1] in ('.', '+', '-', '*', '/')) and (arg in ('.', '+', '-', '*', '/')):
            if len(txt) >= 2:
                if (txt[-1] == '-' and txt[-2] == '*') and arg in ('.', '+', '/'):
                    txt = txt[:-2]
                elif (txt[-1] == '-' and txt[-2] == '/') and arg in ('.', '+', '*'):
                    txt = txt[:-2]
                elif (txt[-1] == '*' and txt[-2] == '*') or (txt[-1] == '/' and txt[-2] == '/'):
                    if arg == '-':
                        txt = txt[:-1]
                    else:
                        txt = txt[:-2]
                elif (arg == '-') and (txt[-1] in ('*', '/')):
                    pass
                elif txt[-1] == '*' and arg == '*':
                    pass
                elif txt[-1] == '/' and arg == '/':
                    pass
                else:
                    txt = txt[:-1]
            else:
                txt = txt[:-1]
            self.line_edit.setText(txt + str(arg))
        elif txt == "MathError":
            if arg in ('.', '+', '-', '*', '/'):
                pass
            else:
                self.line_edit.setText(str(arg))
        elif len(txt) >= 15:  # 限制txt的长度
            pass
        else:
            self.line_edit.setText(txt + str(arg))

    def button_arithmetic(self, arg):
        txt = self.line_edit.text()
        # noinspection PyBroadException
        try:
            ans = str(eval(txt))
        except BaseException:
            ans = "MathError"
            self.clear_event()
            self.line_edit.setText(ans)
        else:
            if len(txt) >= 2:
                if txt[0] == '(' and txt[-1] == ')':
                    txt = txt[1:len(txt) - 1]
            for i in txt[::-1]:
                if i in ('+', '-', '*', '/'):
                    break
                elif i == '.':
                    for j in txt[::-1]:
                        if j == '0':
                            txt = txt[:-1]
                        elif j == '.':
                            txt = txt[:-1]
                            break
                        else:
                            break
                else:
                    pass
            if arg == "negate":  # 取反
                self.line_edit.setText(str(eval(ans + "*-1")))
            elif arg == "reciprocal":  # 倒数
                self.line_ans.setText("1/(" + txt + ")=")
                # noinspection PyBroadException
                try:
                    ans = str(eval("1/" + ans))
                    if len(ans) >= 2:
                        if ans[-1] == '0' and ans[-2] == '.':
                            ans = ans[:-2]
                    if len(ans) > 15:
                        ans = ans[:15]
                    self.line_edit.setText(ans)
                except BaseException:
                    self.clear_event()
                    self.line_edit.setText("MathError")
            elif arg == "square":
                self.line_ans.setText("sqr(" + txt + ")=")
                ans = str(eval(ans + "*" + ans))
                if len(ans) >= 2:
                    if ans[-1] == '0' and ans[-2] == '.':
                        ans = ans[:-2]
                if len(ans) > 15:
                    ans = ans[:15]
                self.line_edit.setText(ans)
            else:
                self.line_ans.setText("√(" + txt + ")=")
                ans = str(eval(ans + "**0.5"))
                if len(ans) >= 2:
                    if ans[-1] == '0' and ans[-2] == '.':
                        ans = ans[:-2]
                if len(ans) > 15:
                    ans = ans[:15]
                self.line_edit.setText(ans)

    def calc_complete(self):
        txt = self.line_edit.text()
        # noinspection PyBroadException
        try:
            ans = str(eval(txt))
        except BaseException:
            ans = "MathError"
            self.clear_event()
            self.line_edit.setText(ans)
        else:
            if len(ans) >= 2:
                if ans[-1] == '0' and ans[-2] == '.':
                    ans = ans[:-2]
            if len(ans) > 15:
                ans = ans[:15]
            self.line_edit.setText(ans)
            for i in txt[::-1]:
                if i in ('+', '-', '*', '/'):
                    break
                elif i == '.':
                    for j in txt[::-1]:
                        if j == '0':
                            txt = txt[:-1]
                        elif j == '.':
                            txt = txt[:-1]
                            break
                        else:
                            break
                else:
                    pass
            self.line_ans.setText(txt + '=')

    def clear_event(self):
        self.line_ans.clear()
        self.line_edit.setText('0')

    def delete_event(self):
        txt = self.line_edit.text()
        if txt == '0' or txt == "MathError":
            pass
        elif len(txt) == 1:
            self.line_edit.setText('0')
        else:
            txt = txt[:len(txt) - 1]
            self.line_edit.setText(txt)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWin = MyMainWindow()
    myWin.show()
    sys.exit(app.exec())